#include <QCoreApplication>
#include<QDateTime>
#include<QDir>
#include<QMutex>
#include<QTextStream>
#include<QTextCodec>
#include"systemfile.h"
#include"datebase.h"
#include"fileinfo.h"
#include"mainaction.h"
#include"maintask.h"
#include"unitclass.h"

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <execinfo.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

#define LOGDIR  "/home/bgjsource/"
#define CORE_SIZE   1024 * 1024 * 500

void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static QMutex mutex;
    mutex.lock();
    QString logTime=QDateTime::currentDateTime().toString("yyyyMMdd hh:mm:ss");
    QString txt;
    switch(type)
    {
    //调试信息提示
    case QtDebugMsg:
        txt = QString("Debug: %1 %2").arg(logTime).arg(msg);
        break;
        //一般的warning提示
    case QtWarningMsg:
        txt = QString("Warning: %1 %2").arg(logTime).arg(msg);
        break;
        //严重错误提示
    case QtCriticalMsg:
        txt = QString("Critical: %1 %2").arg(logTime).arg(msg);
        break;
        //致命错误提示
    case QtFatalMsg:
        txt = QString("Fatal: %1 %2").arg(logTime).arg(msg);
        abort();
    }


    //添加日志文件到指定目录
    QString logDirPath=QString(LOGDIR)+"/log";
    QDir logDir;
    if(!logDir.exists(logDirPath))
    {
        logDir.mkpath(logDirPath);
    }
    logDir.setCurrent(logDirPath);
    QString logname=QDate::currentDate().toString("yyyyMMdd").append(".txt");
    QString delename=QDate::currentDate().addDays(-7).toString("yyyyMMdd").append(".txt");
    QFile outFile(logname);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream ts(&outFile);
    ts << txt << endl;
    QFile defile(delename);
    if(defile.exists())
    {
        defile.remove();
    }
    mutex.unlock();
}

/**************************************************************************************************
**  函数名称:  segv_error_handle
**  功能描述:  段错误的实际处理函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
static void segv_error_handle(int v)
{
    system("sync");

    printf("segv_error(value: %d), reason is %s, proc is going to exit now!!!\n", v, strerror(v));
    const int len=1024;
    void *func[len];
    size_t size;
    int i;
    char **funs;

    signal(v,SIG_DFL);
    size=backtrace(func,len);
    funs=(char**)backtrace_symbols(func,size);
    fprintf(stderr,"System error, Stack trace:\n");
    for(i=0;i<size;++i) fprintf(stderr,"%d %s \n",i,funs[i]);

    free(funs);

    exit(1);
}

/**************************************************************************************************
**  函数名称:  install_segv_handler
**  功能描述:  注册段错误的处理函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
static void install_segv_handler()
{
    struct sigaction siga;

    siga.sa_handler = segv_error_handle;
    siga.sa_flags = 0;

    memset(&siga.sa_mask, 0, sizeof(sigset_t));

    sigaction(SIGSEGV, &siga, NULL);                                           /* 捕获段非法错误的信号 */
    sigaction(SIGTERM, &siga, NULL);                                           /* 捕获软件终止的信号 */
    sigaction(SIGINT,  &siga, NULL);                                           /* 捕获进程中断的信号 */
}
/**************************************************************************************************
**  函数名称:  install_segv_handler
**  功能描述:  打开程序异常时的core文件保存功能
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
int CoreDump (void)
{
    struct rlimit rlmt;
    if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1;
    }
    printf("Before set rlimit CORE dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);

    rlmt.rlim_cur = (rlim_t)CORE_SIZE;
    rlmt.rlim_max  = (rlim_t)CORE_SIZE;

    if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1;
    }

    if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1;
    }
    printf("After set rlimit CORE dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);
}
/**************************************************************************************************
**  函数名称:  ErrorDebug
**  功能描述:  选择出错信息调试功能
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void ErrorDebug(int set)
{
    if(set == 1)
        install_segv_handler();     //打印异常栈信息
    if(set == 2)
        CoreDump();                 //保存core文件
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
//    QCoreApplication::addLibraryPath("/qt/plugins/");
    //qInstallMsgHandler(customMessageHandler);
    //选择出错信息调试功能
    ErrorDebug(2);
    qInstallMessageHandler(outputMessage);
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    QString cmd="/etc/init.d/vsftpd start";
    system(cmd.toLatin1().data());
    //初始化
    systemFile::GetInstance()->readSetting();

    //接收串口数据
    maintask mainTask;

    MainAction w;
    w.start();
    QObject::connect(&w,SIGNAL(sendSql()),&mainTask,SLOT(MaintaskRun()));//串口数据
    QObject::connect(&w,SIGNAL(signalaxis()),&mainTask,SLOT(slotGet()));
    //QObject::connect(&w,SIGNAL(sendSql()),mainTask.fileInfo_task,SLOT(FileInfoRun()));//文件扫描

    //删除多余日志
    deleteOldLog();

    return a.exec();
}

